<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件
use think\facade\Db;
use think\facade\Cache;
use app\common\support\PHPExcelService;
use think\facade\Queue;
use think\facade\Env;

if (!function_exists('get_config')) {
    function get_config($key,$default=''){
        if(Env::get('env') == true){
            //转移服务器
            $value = Env::get($key) ?? $default;
        }else{
            //不转移服务器
            try {
                $nacos = \app\common\support\Nacos::get_instance();
                $value =  $nacos->getConfig($key);
            } catch (\Exception $e) {
                json_response(0,$e->getMessage());
            }
        }
        return $value;
    }
}

if (!function_exists('get_base_config')) {
    function get_base_config($key,$default=''){
        if(Env::get('env') == true){
            //转移服务器
            $value = Env::get($key) ?? $default;
        }else{
            //不转移服务器
            try {
                $nacos = \app\common\support\Nacos::get_instance();
                $value =  $nacos->getBaseConfig($key) ?? $default;
            } catch (\Exception $e) {
                json_response(0,$e->getMessage());
            }
        }
        return $value;
    }
}

/**
 * 获取客户端真实IP地址
 */
if (!function_exists('get_real_ip')) {
    function get_real_ip(){
        static $realip;
        if(isset($_SERVER)){
            if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
                $realip=$_SERVER['HTTP_X_FORWARDED_FOR'];
            }else if(isset($_SERVER['HTTP_CLIENT_IP'])){
                $realip=$_SERVER['HTTP_CLIENT_IP'];
            }else{
                $realip=$_SERVER['REMOTE_ADDR'];
            }
        }else{
            if(getenv('HTTP_X_FORWARDED_FOR')){
                $realip=getenv('HTTP_X_FORWARDED_FOR');
            }else if(getenv('HTTP_CLIENT_IP')){
                $realip=getenv('HTTP_CLIENT_IP');
            }else{
                $realip=getenv('REMOTE_ADDR');
            }
        }
        return $realip;
    }
}

/**
 * 获取两个日期之间所以日期
 * @param [date] $startDate 开始时间
 * @param [date] $endDate 结束时间
 * @param string $format 格式
 * @return void
 * @author Sam
 * @date 2022-12-28
 */
if (!function_exists('createDateRange')) {
    function createDateRange($startDate, $endDate, $format = "Y-m-d")
    {
        $begin = new DateTime($startDate);
        $end = new DateTime($endDate);
    
        $interval = new DateInterval('P1D'); // 1 Day
        $dateRange = new DatePeriod($begin, $interval, $end);
    
        $range = [];
        foreach ($dateRange as $date) {
            $range[] = $date->format($format);
        }
    
        return $range;
    }
}
if (!function_exists('push_queue')) {

    /**
     * 消息队列添加
     * @param string $class_name 执行的当前任务将由哪个类来负责处理。完整路径 调用fire方法
     * @param string $queue_name 队列名称 
     * @param array  $queue_data 队列数组
     * @param int  $later 是否延迟执行   大于0标识延时队列 时间单位秒  执行命令  php think queue:listen --queue testJob  
     */
    function push_queue($class_name,$queue_name,$queue_data,$later=0){
        if($later>0){
       
            //延时队列
             $isPushed = Queue::later($later,$class_name , $queue_data, $queue_name);
        }else{
            //普通队列
          
             $isPushed = Queue::push($class_name , $queue_data, $queue_name);
        }
        if(!$isPushed){
            exception('添加队列失败');
        }
    }
}

if (!function_exists('create_qrcode')) {
    /**
     * 字符串生成二维码  需要先composer安装第三方库   "endroid/qr-code": "^3.5"
     * @param [string] $str 字符串
     * @return void
     * @author Sam
     * @date 2022-11-18
     */
    function create_qrcode($str){
        try {
            $qrCode = new \Endroid\QrCode\QrCode($str);
            $code_server   = $qrCode->writeString();
            $imgs = 'data:png;base64,' . base64_encode($code_server);
            $upload = new \app\common\api\Upload();
            $code_img = $upload->oss()->upload($imgs, 'base64', '.png');
        } catch (\Exception $e) {
            exit($e->getMessage());
        }
        return $code_img;
    }
}   


if (!function_exists('attr_format')) {
    /**
     * 格式化属性
     * @param $arr
     * @return array
     */
    function attr_format($arr)
    {
        $data = [];
        $res = [];
        $count = count($arr);
        if ($count > 1) {
            for ($i = 0; $i < $count - 1; $i++) {
                if ($i == 0) $data = $arr[$i]['detail'];
                //替代变量1
                $rep1 = [];
                foreach ($data as $v) {
                    foreach ($arr[$i + 1]['detail'] as $g) {
                        //替代变量2
                        $rep2 = ($i != 0 ? '' : $arr[$i]['value'] . '_$_') . $v . '-$-' . $arr[$i + 1]['value'] . '_$_' . $g;
                        $tmp[] = $rep2;
                        if ($i == $count - 2) {
                            foreach (explode('-$-', $rep2) as $k => $h) {
                                //替代变量3
                                $rep3 = explode('_$_', $h);
                                //替代变量4
                                $rep4['detail'][$rep3[0]] = isset($rep3[1]) ? $rep3[1] : '';
                            }
                            if($count == count($rep4['detail']))
                                $res[] = $rep4;
                        }
                    }
                }
                $data = isset($tmp) ? $tmp : [];
            }
        } else {
            $dataArr = [];
            foreach ($arr as $k => $v) {
                foreach ($v['detail'] as $kk => $vv) {
                    $dataArr[$kk] = $v['value'] . '_' . $vv;
                    $res[$kk]['detail'][$v['value']] = $vv;
                }
            }
            $data[] = implode('-', $dataArr);
        }
        return [$data, $res];
    }
}

if (!function_exists('exception')) {
    /**
     * 抛出异常处理
     *
     * @param string $msg 异常消息
     * @param integer $code 异常代码 默认为0
     * @param string $exception 异常类
     *
     * @throws Exception
     */
    function exception($msg, $code = 0, $exception = '')
    {
        $e = $exception ?: '\think\Exception';
        throw new $e($msg, $code);
    }
}

/**
 * 接口调用成功返回
 * @param string $msg
 * @param array $data
 * @param int $code
 * @return string
 * @date 2021/1/29 15:22
 */
function success($msg='', $data=[], $code=1) {
    return  json_encode([
        'code'  => $code,
        'msg'   => $msg,
        'data'  => $data,
    ], JSON_UNESCAPED_UNICODE);
}

/**
 * 接口调用失败返回
 * @param string $msg
 * @param array $data
 * @param int $code
 * @return string
 * @date 2021/1/29 15:22
 */
function error($msg='', $data=[], $code=0) {
    return  json_encode([
        'code'  => $code,
        'msg'   => $msg,
        'data'  => $data,
    ], JSON_UNESCAPED_UNICODE);
}

/**
 * 参数检查
 * @param string $name
 * @param bool $default
 * @param string $tips
 * @return array|bool
 */
function param_check($name, $default=false, $tips='') {
    $val = input($name);
    if(!empty($val)) {
        return $val;
    }else {
        if($default !== false) return $default;
        json_response(0, empty($tips) ? "{$name}不能为空" : $tips);
    }
}

/**
 * JSON格式返回数据
 * @param int $code
 * @param string $msg
 * @param array $data
 */
function json_response($code=0, $msg='', $data=[]) {
    echo json_encode([
        'code'  => $code,
        'msg'   => $msg,
        'data'  => $data,
    ], JSON_UNESCAPED_UNICODE);
    exit();
}

/**
 * 获得当前完整URL
 * @param string $request_scheme 请求头
 * @return string
 */
function url_current($request_scheme='https') {
    $redirect_uri = $request_scheme.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    return $redirect_uri;
}

/**
 * 获取redis对象实例
 * @return Redis
 * @date 2020/6/4 14:04
 */
function redis_instance() {
    global $redis;
    if($redis) return $redis;
    $config = config('app.redis');
    $redis  = new \Redis();
    $redis->connect($config['redis_host'], $config['redis_port']);
    $redis->auth($config['redis_pass']);
    $redis->select($config['redis_index']);
    return $redis;
}

/**
 * 读取csv文件转换成数组
 * @param string $csv
 * @return array
 * @date 2020/8/21 16:11
 */
function csv_to_array($csv=''){
    setlocale(LC_ALL, 'zh_CN');
    set_time_limit(0);
    $data = [];
    $fs = fopen($csv,'r');
    $i = 0;
    while ($row = fgetcsv($fs)) {
        $i += 1;
        if($i == 1) continue;
        foreach($row as &$value) {
            $value = iconv('GBK', 'UTF-8', $value);
        }
        $data[] = $row;
    }
    fclose($fs);
    @unlink($csv);
    return $data;
}
/**
 * csv大文件导入
 * @param $csv
 * @return array
 * @date 2020/10/18 15:57
 */
function big_csv_to_array($csv) {
    function big_csv_read($csv) {
        $handle = fopen($csv, 'rb');

        while (!feof($handle)) {
            yield fgetcsv($handle);
        }
        fclose($handle);
    }
    $result = big_csv_read($csv);
    
    $data = [];
    $i = 0;
    foreach($result as $row) {
      if($row) foreach ($row as &$value) {     
            $value = iconv('GBK', 'UTF-8', $value);
        }
 
        $data[] = $row;
    }
    return $data;
}

/**
 * 数组转csv
 * @param array $data 数组
 * @param string $file_name 文件名字
 * @param array $fields 字段介绍
 */
function array_to_csv($data=[], $file_name='', $fields=[]) {
    $header = empty($fields) ? array_keys($data[0]) : array_values($fields);
    $head = [];
    foreach($header as $i=>$value) {
        $value = is_array($value) ? $value[0] : $value;
        $head[$i] = iconv("UTF-8","GBK", $value);
    }
    foreach ($data as $i=>$item) {
        $list = [];
        foreach($fields as $k=>$v) {
            $value = isset($item[$k]) ? $item[$k] : '';
            if(is_array($v)) {
                if(is_array($v[1])) {
                    // 数组类型处理
                    $value = $v[1][$value];
                }else if(is_callable($v[1])) {
                    // 匿名函数处理
                    $value = $v[1]($item);
                }else if(is_string($v[1])) {
                    // 字符串类型处理
                    if($v[1]  == 'datetime') {
                        // 格式化时间戳
                        $value = $value > 0 ? date('Y-m-d H:i:s', $value) : '';
                    }else if(!empty($v[1])) {
                        // 设置字段默认值
                        $value = $v[1];
                    }
                }
            }
            // 处理数字变为科学计数法的问题
            if(is_numeric($value) && strlen($value) > 10) $value .= "\t";
            if(mb_substr($value, 0, 1) == 0) $value .= "\t";
            $list[$k] = iconv("UTF-8","GBK", (string)$value);
        }
    }
    return $list;
}


// 列出文件和目录

function _scandir($dir) {

    if(function_exists('scandir')) return scandir($dir);   // 有些服务器禁用了scandir

    $dh = opendir($dir);

    $arr = array();

    while($file = readdir($dh)) {

        if($file == '.' || $file == '..') continue;

        $arr[] = $file;

    }

    closedir($dh);

    return $arr;

}

// 递归删除目录

function _rmdir($dir, $keepdir = 0) {

    if(!is_dir($dir) || $dir == '/' || $dir == '../') return FALSE;    // 避免意外删除整站数据

    $files = _scandir($dir);

    foreach($files as $file) {

        if($file == '.' || $file == '..') continue;

        $filepath = $dir.'/'.$file;

        if(!is_dir($filepath)) {

            try{unlink($filepath);}catch(Exception $e){}

        }else{

            _rmdir($filepath);

        }

    }

    if(!$keepdir) try{rmdir($dir);}catch(Exception $e){}

    return TRUE;

}

/**
 * 大文件导出
 * @param $db
 * @param string $file_name
 * @param array $fields
 * @param $callback
 * @date 2020/11/7 15:59
 */
function big_array_to_csv($db, $file_name, $fields=[], $callback='') {
   
    set_time_limit(0);
    ini_set('memory_limit', '5G');
    error_reporting(0);
    // 表头
    header('Content-Type: application/csv');   // header设置
    header("Content-Disposition: attachment;filename=".($file_name ? $file_name : '导出').".csv");
    header('Cache-Control: max-age=0');
   
    $fp = fopen('php://output','w');

    $header = empty($fields) ? array_keys($db->order('id')->find()->toArray()) : array_values($fields);
   
    $head = [];
    foreach($header as $i=>$value) {
        $value = is_array($value) ? $value[0] : $value;
        $head[$i] = iconv("UTF-8","GBK", $value);
    }
    
    fputcsv($fp,$head);

    $total = $db->count();
    
    $page_size = 1;//每次只从数据库取10000条以防变量缓存太大

    for($o=0; $o<ceil($total/$page_size); $o++) {
   
        $data = $db->limit($o*$page_size, $page_size)->select()->toArray();
        $data = is_callable($callback) ? $callback($data) : $data;
        foreach ($data as $i=>$item) {
            $list = [];
            foreach($fields as $k=>$v) {
                $value = isset($item[$k]) ? $item[$k] : '';
                if(is_array($v)) {
                    if(is_array($v[1])) {
                        // 数组类型处理
                        $value = $v[1][$value];
                    }else if(is_callable($v[1])) {
                        // 匿名函数处理
                        $value = $v[1]($item);
                    }else if(is_string($v[1])) {
                        // 字符串类型处理
                        if($v[1]  == 'datetime') {
                            // 格式化时间戳
                            $value = $value > 0 ? date('Y-m-d H:i:s', $value) : '';
                        }else if(!empty($v[1])) {
                            // 设置字段默认值
                            $value = $v[1];
                        }
                    }
                }
                // 处理数字变为科学计数法的问题
                if(is_numeric($value) && strlen($value) > 10) $value .= "\t";
                if(mb_substr($value, 0, 1) == 0) $value .= "\t";
                $list[$k] = iconv("UTF-8","GBK", (string)$value);
            }
            
            fputcsv($fp, $list);
        }

        // 刷新一下输出buffer，防止由于数据过多造成问题
        ob_flush();
        flush();
    }
    fclose($output);
    // exit();
}

/**
 * base64转图片
 * @param [type] $contents
 * @param [type] $mime
 * @return void
 * @author Sam
 * @date 2021-04-01
 */
 function data_uri($contents, $mime = 'image/jpeg')
{
    $base64 = base64_encode($contents);
    return ('data:' . $mime . ';base64,' . $base64);
}

function create_guid() {
    $charid = strtoupper(md5(uniqid(mt_rand(), true)));
    $hyphen = chr(45);// "-"
    $uuid = chr(123)// "{"
        .substr($charid, 0, 8).$hyphen
        .substr($charid, 8, 4).$hyphen
        .substr($charid,12, 4).$hyphen
        .substr($charid,16, 4).$hyphen
        .substr($charid,20,12)
        .chr(125);// "}"
    return $uuid;
}

//构造金蝶Web API请求格式
function create_postdata($args) {
    $postdata = array(
        'format'=>1,
        'useragent'=>'ApiClient',
        'rid'=>create_guid(),
        'parameters'=>$args,
        'timestamp'=>date('Y-m-d'),
        'v'=>'1.0'
    );

    return json_encode($postdata);
}

if(!function_exists('jd_post')){
    /**
     * 金蝶erp请求
     * @param [type] $url
     * @param [type] $post_content
     * @param [type] $cookie_jar
     * @param [type] $isLogin
     * @return void
     * @author Sam
     * @date 2021-01-07
     */
     function invoke_post($url,$post_content,$cookie_jar,$isLogin)
        {
            $ch = curl_init($url);

            $this_header = array(
                'Content-Type: application/json',
                'Content-Length: '.strlen($post_content)
            );

            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

            curl_setopt($ch, CURLOPT_HTTPHEADER, $this_header);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_content);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            if($isLogin){
                curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_jar);
            }
            else{
                curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_jar);
            }
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);

            $result = curl_exec($ch);
            curl_close($ch);

            return $result;
        }
}
if(!function_exists('curl')){
    /**
 * Curl操作
 * @param string $type 请求类型 'POST' 或 'GET' 大小写都可以
 * @param string $url 请求地址 url
 * @param array $data 数组 cookie 请求cookie data post请求数据
 * @param bool $headerFile 返回头信息 如果页面做了跳转 则可以从返回头信息获得跳转地址，应用场景不多
 * @return bool|mixed
 */
function curl($type, $url, $data=[], $headerFile=false) {
        $type = strtoupper($type);
        $type_list = ['POST', 'GET', 'PUT'];
        if(!in_array($type, $type_list)) $type = 'POST';
        $ch = curl_init();
        // 请求类型
        if($type == 'POST') {
            curl_setopt($ch, CURLOPT_POST, 1);
        }else if($type == 'PUT') {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST,"PUT"); //设置请求方式
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        curl_setopt($ch, CURLOPT_ENCODING, ''); // 这个是解释gzip内容, 解决获取结果乱码 gzip,deflate
        // 是否存在请求字段信息
        if(!empty($data['data'])) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data['data']);
        }
        // 是否存在cookie
        if(!empty($data['cookie'])) {
            curl_setopt($ch, CURLOPT_COOKIE, $data['cookie']);
        }
        // 请求头
        if(!empty($data['header'])) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $data['header']);
        }

        // 证书
        if(!empty($data['ssl_cert'])) {
            curl_setopt($ch,CURLOPT_SSLCERT, $data['ssl_cert']);
        }
        if(!empty($data['ssl_key'])) {
            curl_setopt($ch,CURLOPT_SSLKEY, $data['ssl_key']);
        }

        // 返回ResponseHeader
        if($headerFile) {
            curl_setopt($ch, CURLOPT_HEADER, 1);
        }
        // 设置请求超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, 6);
        // 发送请求
        $result = curl_exec($ch);
        if (curl_errno($ch)) return false;
        curl_close($ch);
        return $result;
    }
}


//驼峰命名转下划线命名
function toUnderScore($str)
{
    $dstr = preg_replace_callback('/([A-Z]+)/',function($matchs)
    {
        return '_'.strtolower($matchs[0]);
    },$str);
    return trim(preg_replace('/_{2,}/','_',$dstr),'_');
}

//下划线命名到驼峰命名
function toCamelCase($str)
{
    $array = explode('_', $str);
    $result = $array[0];
    $len=count($array);
    if($len>1)
    {
        for($i=1;$i<$len;$i++)
        {
            $result.= ucfirst($array[$i]);
        }
    }
    return $result;
}

function createNoncestr($length = 32)
{
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    $str = "";
    for ($i = 0; $i < $length; $i++) {
        $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
    }
    return $str;
}

/**
 * Notes:数组转xml
 * User: rhm
 * Date: 2020/1/3 0003
 * Time: 18:33
 */
function array_to_xml($arr)
{
    if (!is_array($arr)
        || count($arr) <= 0) {
        throw new WxPayException("数组数据异常！");
    }
    $xml = "<xml>";
    foreach ($arr as $key => $val) {
        if (is_numeric($val)) {
            $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
        } else {
            $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
        }
    }
    $xml .= "</xml>";
    return $xml;
}

/**
 * Notes:xml转数组
 * User: rhm
 * Date: 2020/1/3 0003
 * Time: 18:33
 */
function xml_to_array($xml)
{
    //将XML转为array
    $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    return $array_data;
}




/**
 * Notes:返回json
 * User: rhm
 * Date: 2019/12/23 0023
 * Time: 11:26
 */
if (!function_exists('show')) {
    function show($code, $msg = ' ', $data = [])
    {
        $result = [
            'code' => $code,
            'msg' => $msg,
            'data' => $data
        ];
        exit(json_encode($result,JSON_UNESCAPED_UNICODE));
    }
}

if (!function_exists('sys_config')) {
    /**
     * 获取系统单个配置
     * @param string $name
     * @param string $default
     * @return string
     */
    function sys_config(string $name, $default = '')
    {
        if (empty($name))
            return $default;

        $config = trim(app('sysConfig')->get($name));
        if ($config === '' || $config === false) {
            return $default;
        } else {
            return $config;
        }
    }
}

/**
 * 模拟tab产生空格
 * @param int $step
 * @param string $string
 * @param int $size
 * @return string
 */
function tab($step = 1, $string = ' ', $size = 4)
{
    return str_repeat($string, $size * $step);
}

/**
 * @return redis
 */
function getRedis(){
   try{
        $config = config('cache.redis');
        $redis= new \Redis();
        $redis->connect($config['redis_host'], $config['redis_port']); //连接Redis
        $redis->auth($config['redis_pass']); //密码验证
        $redis->select($config['redis_index']);//选择数据库
   }catch(\Exception $e){
       exit('REDIS连接失败:'.$e->getMessage());
   }
    
    return $redis;
}

if (!function_exists('sys_data')) {
    /**
     * 获取系统单个配置
     * @param string $name
     * @return string
     */
    function sys_data(string $name, int $limit = 0)
    {
        return app('sysGroupData')->getData($name, $limit);
    }
}

if (!function_exists('filter_emoji')) {

    // 过滤掉emoji表情
    function filter_emoji($str)
    {
        $str = preg_replace_callback(    //执行一个正则表达式搜索并且使用一个回调进行替换
            '/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $str);
        return $str;
    }
}


if (!function_exists('str_middle_replace')) {
    /** TODO 系统未使用
     * @param string $string 需要替换的字符串
     * @param int $start 开始的保留几位
     * @param int $end 最后保留几位
     * @return string
     */
    function str_middle_replace($string, $start, $end)
    {
        $strlen = mb_strlen($string, 'UTF-8');//获取字符串长度
        $firstStr = mb_substr($string, 0, $start, 'UTF-8');//获取第一位
        $lastStr = mb_substr($string, -1, $end, 'UTF-8');//获取最后一位
        return $strlen == 2 ? $firstStr . str_repeat('*', mb_strlen($string, 'utf-8') - 1) : $firstStr . str_repeat("*", $strlen - 2) . $lastStr;

    }
}


if (!function_exists('sensitive_words_filter')) {

    /**
     * 敏感词过滤
     *
     * @param string
     * @return string
     */
    function sensitive_words_filter($str)
    {
        if (!$str) return '';
        $file = app()->getAppPath() . 'public/static/plug/censorwords/CensorWords';
        $words = file($file);
        foreach ($words as $word) {
            $word = str_replace(array("\r\n", "\r", "\n", "/", "<", ">", "=", " "), '', $word);
            if (!$word) continue;

            $ret = preg_match("/$word/", $str, $match);
            if ($ret) {
                return $match[0];
            }
        }
        return '';
    }
}

if (!function_exists('make_path')) {

    /**
     * 上传路径转化,默认路径
     * @param $path
     * @param int $type
     * @param bool $force
     * @return string
     */
    function make_path($path, int $type = 2, bool $force = false)
    {
        $path = DS . ltrim(rtrim($path));
        switch ($type) {
            case 1:
                $path .= DS . date('Y');
                break;
            case 2:
                $path .= DS . date('Y') . DS . date('m');
                break;
            case 3:
                $path .= DS . date('Y') . DS . date('m') . DS . date('d');
                break;
        }
        try {
            if (is_dir(app()->getRootPath() . 'public' . DS . 'uploads' . $path) == true || mkdir(app()->getRootPath() . 'public' . DS . 'uploads' . $path, 0777, true) == true) {
                return trim(str_replace(DS, '/', $path), '.');
            } else return '';
        } catch (\Exception $e) {
            if ($force)
                throw new \Exception($e->getMessage());
            return '无法创建文件夹，请检查您的上传目录权限：' . app()->getRootPath() . 'public' . DS . 'uploads' . DS . 'attach' . DS;
        }

    }
}


if (!function_exists('curl_file_exist')) {
    /**
     * CURL 检测远程文件是否在
     * @param $url
     * @return bool
     */
    function curl_file_exist($url)
    {
        $ch = curl_init();
        try {
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_HEADER, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
            $contents = curl_exec($ch);
            if (preg_match("/404/", $contents)) return false;
            if (preg_match("/403/", $contents)) return false;
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }
}
if (!function_exists('set_file_url')) {
    /**
     * 设置附加路径
     * @param $url
     * @return bool
     */
    function set_file_url($image, $siteUrl = '')
    {
        if (!strlen(trim($siteUrl))) $siteUrl = sys_config('site_url');
        $domainTop = substr($image, 0, 4);
        if ($domainTop == 'http') return $image;
        $image = str_replace('\\', '/', $image);
        return $siteUrl . $image;
    }
}

if (!function_exists('set_http_type')) {
    /**
     * 修改 https 和 http
     * @param $url $url 域名
     * @param int $type 0 返回https 1 返回 http
     * @return string
     */
    function set_http_type($url, $type = 0)
    {
        $domainTop = substr($url, 0, 5);
        if ($type) {
            if ($domainTop == 'https') $url = 'http' . substr($url, 5, strlen($url));
        } else {
            if ($domainTop != 'https') $url = 'https:' . substr($url, 5, strlen($url));
        }
        return $url;
    }

}


/**
 * 缓存处理
 */
function freshCache($config_key,$data = array()){
	$param = explode('.', $config_key);
    $config = [];
    if(empty($data)){
        $res = Db::name('config')->where("inc_type",$param[0])->select();
        if($res){
            foreach($res as $k=>$val){
                $config[$val['name']] = $val['value'];
            }
        }
        if(count($param)>1){
            return $config[$param[1]];
        }else{
            return $config;
        }
    }else{
        //更新缓存
        $result =  Db::name('config')->where("inc_type", $param[0])->select();
        if($result){
            foreach($result as $val){
                $temp[$val['name']] = $val['value'];
            }
            foreach ($data as $k=>$v){
                $newArr = array('name'=>$k,'value'=>trim($v),'inc_type'=>$param[0]);
                if(!isset($temp[$k])){
                    Db::name('config')->insert($newArr);//新key数据插入数据库
                }else{
                    if($v!=$temp[$k])
                        Db::name('config')->where("name", $k)->update($newArr);//缓存key存在且值有变更新此项
                }
            }
            //更新后的数据库记录
            $newRes = Db::name('config')->where("inc_type", $param[0])->select();
            foreach ($newRes as $rs){
                $newData[$rs['name']] = $rs['value'];
            }
        }else{
            foreach($data as $k=>$v){
                $newArr[] = array('name'=>$k,'value'=>trim($v),'inc_type'=>$param[0]);
            }
            Db::name('config')->insertAll($newArr);
            $newData = $data;
        }
        return cache($param[0],$newData);
    }
}

if (!function_exists('check_card')) {
    /**
     * 身份证验证
     * @param $card
     * @return bool
     */
    function check_card($card)
    {
        $city = [11 => "北京", 12 => "天津", 13 => "河北", 14 => "山西", 15 => "内蒙古", 21 => "辽宁", 22 => "吉林", 23 => "黑龙江 ", 31 => "上海", 32 => "江苏", 33 => "浙江", 34 => "安徽", 35 => "福建", 36 => "江西", 37 => "山东", 41 => "河南", 42 => "湖北 ", 43 => "湖南", 44 => "广东", 45 => "广西", 46 => "海南", 50 => "重庆", 51 => "四川", 52 => "贵州", 53 => "云南", 54 => "西藏 ", 61 => "陕西", 62 => "甘肃", 63 => "青海", 64 => "宁夏", 65 => "新疆", 71 => "台湾", 81 => "香港", 82 => "澳门", 91 => "国外 "];
        $tip = "";
        $match = "/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/";
        $pass = true;
        if (!$card || !preg_match($match, $card)) {
            //身份证格式错误
            $pass = false;
        } else if (!$city[substr($card, 0, 2)]) {
            //地址错误
            $pass = false;
        } else {
            //18位身份证需要验证最后一位校验位
            if (strlen($card) == 18) {
                $card = str_split($card);
                //∑(ai×Wi)(mod 11)
                //加权因子
                $factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
                //校验位
                $parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
                $sum = 0;
                $ai = 0;
                $wi = 0;
                for ($i = 0; $i < 17; $i++) {
                    $ai = $card[$i];
                    $wi = $factor[$i];
                    $sum += $ai * $wi;
                }
                $last = $parity[$sum % 11];
                if ($parity[$sum % 11] != $card[17]) {
                    //                        $tip = "校验位错误";
                    $pass = false;
                }
            } else {
                $pass = false;
            }
        }
        if (!$pass) return false;/* 身份证格式错误*/
        return true;/* 身份证格式正确*/
    }
}
if (!function_exists('anonymity')) {
    /**
     * 匿名处理处理用户昵称
     * @param $name
     * @return string
     */
    function anonymity($name)
    {
        $strLen = mb_strlen($name, 'UTF-8');
        $min = 3;
        if ($strLen <= 1)
            return '*';
        if ($strLen <= $min)
            return mb_substr($name, 0, 1, 'UTF-8') . str_repeat('*', $min - 1);
        else
            return mb_substr($name, 0, 1, 'UTF-8') . str_repeat('*', $strLen - 1) . mb_substr($name, -1, 1, 'UTF-8');
    }
}

    /**
     * 一维数据数组生成数据树
     * @param array $list 数据列表
     * @param string $id 父ID Key
     * @param string $pid ID Key
     * @param string $son 定义子数据Key
     * @return array
     */
     function arr2tree($list, $id = 'id', $pid = 'pid', $son = 'sub')
    {
        list($tree, $map) = [[], []];
        foreach ($list as $item) $map[$item[$id]] = $item;
        foreach ($list as $item) if (isset($item[$pid]) && isset($map[$item[$pid]])) {
            $map[$item[$pid]][$son][] = &$map[$item[$id]];
        } else $tree[] = &$map[$item[$id]];
        unset($map);
        return $tree;
    }

    /**
     * 递归
     * @param [type] $pid
     * @param [type] $arr
     * @param array $tree
     * @return void
     * @author Sam
     * @date 2021-03-04
     */
    function create_tree_list($arr, $pid = 0 , &$tree = []){
        foreach ( $arr as $key => $vo ){
            if( $vo['pid'] == $pid ){
                $c= create_tree_list( $arr,$vo['id']);
                if( $c ){
                    $vo['children'] = $c;
                }
                $tree[] = $vo;
            }
        }
        return $tree;
    }

    /**
     * 一维数据数组生成数据树
     * @param array $list 数据列表
     * @param string $id ID Key
     * @param string $pid 父ID Key
     * @param string $path
     * @param string $ppath
     * @return array
     */
  function arr2table(array $list, $id = 'id', $pid = 'pid', $path = 'path', $ppath = '')
    {
        $tree = [];
        foreach (arr2tree($list, $id, $pid) as $attr) {
            $attr[$path] = "{$ppath}-{$attr[$id]}";
            $attr['sub'] = isset($attr['sub']) ? $attr['sub'] : [];
            $attr['spt'] = substr_count($ppath, '-');
            $attr['spl'] = str_repeat("&nbsp;&nbsp;&nbsp;├&nbsp;&nbsp;", $attr['spt']);
            $sub = $attr['sub'];
            unset($attr['sub']);
            $tree[] = $attr;
            if (!empty($sub)) $tree = array_merge($tree, arr2table($sub, $id, $pid, $path, $attr[$path]));
        }
        return $tree;
    }

if (!function_exists('sort_list_tier')) {
    /**
     * 分级排序
     * @param $data
     * @param int $pid
     * @param string $field
     * @param string $pk
     * @param string $html
     * @param int $level
     * @param bool $clear
     * @return array
     */
    function sort_list_tier($data, $pid = 0, $field = 'pid', $pk = 'id', $html = '|-----', $level = 1, $clear = true)
    {
        static $list = [];
        if ($clear) $list = [];
        foreach ($data as $k => $res) {
            if ($res[$field] == $pid) {
                $res['html'] = str_repeat($html, $level);
                $list[] = $res;
                unset($data[$k]);
                sort_list_tier($data, $res[$pk], $field, $pk, $html, $level + 1, false);
            }
        }
        return $list;
    }
}

if (!function_exists('time_tran')) {
    /**
     * 时间戳人性化转化
     * @param $time
     * @return string
     */
    function time_tran($time)
    {
        $t = time() - $time;
        $f = array(
            '31536000' => '年',
            '2592000' => '个月',
            '604800' => '星期',
            '86400' => '天',
            '3600' => '小时',
            '60' => '分钟',
            '1' => '秒'
        );
        foreach ($f as $k => $v) {
            if (0 != $c = floor($t / (int)$k)) {
                return $c . $v . '前';
            }
        }
    }
}

if (!function_exists('url_to_path')) {
    /**
     * url转换路径
     * @param $url
     * @return string
     */
    function url_to_path($url)
    {
        $path = trim(str_replace('/', DS, $url), DS);
        if (0 !== strripos($path, 'public'))
            $path = 'public' . DS . $path;
        return app()->getRootPath() . $path;
    }
}

if (!function_exists('path_to_url')) {
    /**
     * 路径转url路径
     * @param $path
     * @return string
     */
    function path_to_url($path)
    {
        return trim(str_replace(DS, '/', $path), '.');
    }
}

if (!function_exists('image_to_base64')) {
    /**
     * 获取图片转为base64
     * @param string $avatar
     * @return bool|string
     */
    function image_to_base64($avatar = '', $timeout = 9)
    {
        try {
            $url = parse_url($avatar);
            $url = $url['host'];
            $header = [
                'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0',
                'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
                'Accept-Encoding: gzip, deflate, br',
                'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                'Host:' . $url
            ];
            $dir = pathinfo($url);
            $host = $dir['dirname'];
            $refer = $host . '/';
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_REFERER, $refer);
            curl_setopt($curl, CURLOPT_URL, $avatar);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
            curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
            $data = curl_exec($curl);
            $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            curl_close($curl);
            if ($code == 200) {
                return "data:image/jpeg;base64," . base64_encode($data);
            } else {
                return false;
            }
        } catch (\Exception $e) {
            return false;
        }
    }
}

if (!function_exists('put_image')) {
    /**
     * 获取图片转为base64
     * @param string $avatar
     * @return bool|string
     */
    function put_image($url, $filename = '')
    {

        if ($url == '') {
            return false;
        }
        try {
            if ($filename == '') {

                $ext = pathinfo($url);
                if ($ext['extension'] != "jpg" && $ext['extension'] != "png" && $ext['extension'] != "jpeg") {
                    return false;
                }
                $filename = time() . "." . $ext['extension'];
            }

            //文件保存路径
            ob_start();
            readfile($url);
            $img = ob_get_contents();
            ob_end_clean();
            $path = 'uploads/qrcode';
            $fp2 = fopen($path . '/' . $filename, 'a');
            fwrite($fp2, $img);
            fclose($fp2);
            return $path . '/' . $filename;
        } catch (\Exception $e) {
            return false;
        }
    }
}


if (!function_exists('debug_file')) {
    /**
     * 文件调试
     * @param $content
     */
    function debug_file($content, string $fileName = 'error', string $ext = 'txt')
    {
        $msg = '[' . date('Y-m-d H:i:s', time()) . '] [ DEBUG ] ';
        $pach = app()->getRuntimePath();
        file_put_contents($pach . $fileName . '.' . $ext, $msg . print_r($content, true) . "\r\n", FILE_APPEND);
    }
}


if (!function_exists('sql_filter')) {
    /**
     * sql 参数过滤
     * @param string $str
     * @return mixed
     */
    function sql_filter(string $str)
    {
        $filter = ['select ', 'insert ', 'update ', 'delete ', 'drop', 'truncate ', 'declare', 'xp_cmdshell', '/add', ' or ', 'exec', 'create', 'chr', 'mid', ' and ', 'execute'];
        $toupper = array_map(function ($str) {
            return strtoupper($str);
        }, $filter);
        return str_replace(array_merge($filter, $toupper, ['%20']), '', $str);
    }
}

if (!function_exists('is_brokerage_statu')) {

    /**
     * 是否能成为推广人
     * @param float $price
     * @return bool
     */
    function is_brokerage_statu(float $price)
    {
        $storeBrokerageStatus = sys_config('store_brokerage_statu', 1);
        if ($storeBrokerageStatus == 1) {
            return false;
        } else {
            $storeBrokeragePrice = sys_config('store_brokerage_price', 0);
            return $price >= $storeBrokeragePrice;
        }
    }
}

if (!function_exists('array_unique_fb')) {
    /**
     * 二维数组去掉重复值
     * @param $array
     * @return array
     */
    function array_unique_fb($array)
    {
        $out = array();
        foreach ($array as $key => $value) {
            if (!in_array($value, $out)) {
                $out[$key] = $value;
            }
        }
        $out = array_values($out);
        return $out;
    }
}

/**
 * redis锁
 * @param $lock
 * @param $param
 * @param $func
 * @param int $ttl
 * @date 2020/8/17 15:31
 */
function redis_lock($lock, $param, $func, $ttl=15) {
    $redis = redis_instance();
    $res   = $redis->setnx($lock, '1');
    if(!$res) json_response(0, '请求过快，请稍后再试哦~');
    $redis->expire($lock, $ttl);
    $result = $func($param, $redis);
    // $redis->del($lock);
    exit($result);
}

/**
 * redis数据缓存
 * @param string $key redis键名
 * @param mixed $func 闭包方法
 * @param int $ttl 缓存时间
 * @return mixed
 * @date 2021/3/19 14:13
 */
function redis_get($key, $func, $ttl=15) {
    $redis = redis_instance();
    if($redis->exists($key)) {
        return json_decode($redis->get($key), true);
    }else {
        $data = $func();
        $redis->set($key, json_encode($data, JSON_UNESCAPED_UNICODE), $ttl);
        return $data;
    }
}

/**
 * 抽奖方法
 * @param array $prize_list 奖品列表
 * @param string $ratio_key 代表概率的键名
 * @return mixed
 * @date 2021/3/19 14:22
 */
function draw($prize_list=[], $ratio_key='') {
    if(empty($prize_list)) json_response(0, '奖品列表不可为空');
    $result = '';
    // 概率数组的总概率精度
    $radioSum = array_sum(array_column($prize_list, $ratio_key));
    //概率数组循环
    foreach ($prize_list as $key => $prize) {
        $randNum = mt_rand(1, $radioSum);
        if ($randNum <= $prize[$ratio_key]) {
            $result = $key;
            break;
        } else {
            $radioSum -= $prize[$ratio_key];
        }
    }
    return $prize_list[$result];
}


/**
 * aes加密数据
 * @param string $data 加密前的字符串
 * @param string $key key
 * @param string $iv iv
 * @param string $method 加密方法
 * @return string
 * @date 2020/6/22 15:38
 *
 */
function aes_encrypt($data='', $key='', $iv='', $method='aes-128-cbc') {
    return openssl_encrypt($data, $method, $key, 0, $iv);
}

/**
 * aes解密
 * @param string $data 加密前的字符串
 * @param string $key key
 * @param string $iv iv
 * @param string $method 加密方法
 * @return string
 * @date 2020/6/22 15:40
 */
function aes_decrypt($data='', $key='', $iv='', $method='aes-128-cbc') {
    $data = openssl_decrypt($data, $method, $key, OPENSSL_ZERO_PADDING , $iv);
    return trim($data);
}

/**
 * 递归创建目录
 * @param string $dir
 * @return bool
 */
function folder_build($dir='') {
    if(!is_dir($dir)) {
        while(!is_dir(dirname($dir))) {
            if(!folder_build(dirname($dir))) {
                json_response(0, $dir.'目录写入失败');
            }
        }
        if(!is_writable($dir)) {
            return mkdir($dir, 0777, true);
        }else {
            json_response(0,$dir.'目录不可写');
        }
    }
}




/**
 * 数组无限级分类
 * @param $arr
 * @param bool $sub_list // 是否放在子数组内
 * @param $key_val // 第一级的上级ID参数值
 * @param array $config
 * @param int $level
 * @return array
 */
function arr_tree($arr, $sub_list=false, $key_val=0, $config=[], $level=1) {
    $parent_key = isset($config['parent_key']) ? $config['parent_key'] : 'parent_id'; // 上级ID参数名称
    $key        = isset($config['key']) ? $config['key'] : 'id'; // 主键ID参数名称
    $res = array();
    foreach ($arr as $k=>$item) {
        if($item[$parent_key] == $key_val) {
            unset($arr[$k]);
            $item['level'] = $level;
            if($sub_list) {
                $item['sub_list'] = arr_tree($arr, $sub_list, $item[$key], $config, $level + 1);
                $res[] = $item;
            }else {
                $res[] = $item;
                $res = array_merge($res , arr_tree($arr, $sub_list, $item[$key], $config,$level + 1));
            }
        }
    }
    return $res;
}

/**
 * 生成随机字符串
 * @param int $lenth
 * @return string
 */
function str_random($lenth=6) {
    $base = 'qwertyuiopasdfghjklzxcvbnm0123456789QWERTYUIOPASDFGHJKLZXCVBNM';
    $str = '';
    for($i=1; $i<=$lenth; $i++) {
        $str .= $base[mt_rand(0, strlen($base) - 1)];
    }
    return $str;
}

/**
 * 递归读取目录内容
 * @param string $root_path
 * @return array
 * @date 2020/8/6 21:24
 */
function folder_read($root_path=''){
    $files     = [];
    if(!is_dir($root_path)) return [];
    $dh = opendir($root_path);
    while ($file = readdir($dh)) {
        if($file == '.' || $file == '..') {
            continue;
        }
        if(is_dir($root_path.$file)) {
            $files[$file] = folder_read($root_path.$file.'/');
        }else {
            $files[] = $file;
        }
    }
    closedir($dh);
    return $files;
}

/**
 * 取文本中间内容
 * @param $str
 * @param $start
 * @param $end
 * @return bool|string
 * @date 2020/11/2 21:13
 */
function str_get_middle($str, $start, $end) {
    $start_position = strpos($str, $start);
    $end_position   = strpos($str, $end);
    return substr($str, $start_position+strlen($start), $end_position-strlen($start)-$start_position);
}


/**
 * 下载多个文件为zip
 * @param $file_list
 * @date 2021/3/15 16:38
 */
function download_files($file_list) {
    // 设置临时内存大小
    ini_set('memory_limit', '500M');
    set_time_limit(0);
    $file_name = time().'.zip';
    $zip = new \ZipArchive();
    // 创建一个空ZIP文件
    if ($zip->open($file_name, \ZipArchive::CREATE) === TRUE) {
        foreach ($file_list as $key => $value) {
            if(is_numeric($key)) {
                $name = $key.'.png';
            }else {
                $name = $key;
            }
            $zip->addFromString($name , file_get_contents($value));
        }
        $zip->close();
        $fp = fopen($file_name,"r");
        $file_size = filesize($file_name);//获取文件的字节
        //下载文件需要用到的头
        Header("Content-type: application/octet-stream");
        Header("Accept-Ranges: bytes");
        Header("Accept-Length:".$file_size);
        Header("Content-Disposition: attachment; filename=$file_name");
        $buffer=1024; //设置一次读取的字节数，每读取一次，就输出数据（即返回给浏览器）
        $file_count=0; //读取的总字节数
        //向浏览器返回数据 如果下载完成就停止输出，如果未下载完成就一直在输出。根据文件的字节大小判断是否下载完成
        while(!feof($fp) && $file_count<$file_size){
            $file_con=fread($fp,$buffer);
            $file_count+=$buffer;
            echo $file_con;
        }
        fclose($fp);
        //下载完成后删除压缩包，临时文件夹
        if($file_count >= $file_size) {
            unlink($file_name);
        }
    }
    exit;
}

            /**
     * 字符串命名风格转换
     * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
     * @access public
     * @param  string  $name 字符串
     * @param  integer $type 转换类型
     * @param  bool    $ucfirst 首字母是否大写（驼峰规则）
     * @return string
     */
    function parseName($name, $type = 0, $ucfirst = true)
    {
        if ($type) {
            $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
                return strtoupper($match[1]);
            }, $name);
            return $ucfirst ? ucfirst($name) : lcfirst($name);
        }

        return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
    }


      /**
    * @name: 获取加密key,iv
    * @Author: Sam
    * @Date: 2020-07-06 14:04:14
    * @msg:
    * @param {type}
    * @return:
    */
    function getKey($openid)
   {
        $redis_service = redis_instance();
        $temp_key      = str_random(16);
        $temp_iv       = str_random(16);
        $redis_service->hmset($key,array("temp_key"=>$temp_key,'temp_iv'=>$temp_iv));
        $redis_service->expire($key,3600);
        $aes_data=$redis_service->hgetall($key);
        $result = ['key' => base64_encode($aes_data['temp_key']), 'iv' => base64_encode($aes_data['temp_iv'])];
        return $result;
   }

       /**
     * 分数解密
     * @param $key
     * @param $iv
     * @param $encrypted
     * @return mixed
     */
    function encrypt_key($key, $iv, $encrypted)
    {
        $decrypted = openssl_decrypt($encrypted, 'aes-128-cbc', $key, OPENSSL_ZERO_PADDING, $iv);
        $temp = json_encode($decrypted);
        $data = json_decode(str_replace("\u0000", "", $temp));
        $obj = json_decode($data, true);
        return $obj;
    }

   /**
    * pdf文件添加水印
    * @param [type] 水印文字
    * @return void
    * @author Sam
    * @date 2022-10-26
    */
   function waterPdf($string){
    $mpdf = new \Mpdf\Mpdf([
        'autoScriptToLang' => true,
        'autoLangToFont'   => true,
        'useSubstitutions' => true,
    ]);
    $w = '水印文字';
    $mpdf->SetWatermarkText($w, 0.3);//水印文字，透明度
    $mpdf->showWatermarkText = true; //开启水印
    //$mpdf->watermarkAngle = '180';//水印角度
    if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $w, $match)) {
        //如果有中文就添加
        $mpdf->watermark_font = 'fzxkjw';//中文水印不乱码
    }
    // $mpdf->SetImportUse();
    $pageCount = $mpdf->SetSourceFile(APP_PATH.'static/upload/demo.pdf'); //读取原始文件页数
    for ($i=1; $i<=$pageCount; $i++) { //循环添加原始文件
        $import_page = $mpdf->ImportPage($i);
        $mpdf->UseTemplate($import_page);
        if ($i < $pageCount)
            $mpdf->AddPage();
        }
    $mpdf->Output(APP_PATH.'static/upload/new.pdf', 'F'); //保存新文件
    die;
   }


   if (!function_exists('create_order_no')) {
          //生成订单编号
          function create_order_no($table = 'order', $field = 'order_sn', $prefix = 'OD')
          {
              $order_sn = $prefix . date('YmdHis') . rand(10, 99);
              while (1) {
                  $count = Db::name("{$table}")->where([$field => $order_sn])->count();
                  if ($count <= 0) {
                      break;
                  }
                  $order_sn = $prefix . date('YmdHis') . rand(10, 99);
              }
              return $order_sn;
          }
   }

